package com.my;

import com.my.config.Flag;
import com.my.config.GlobalConfig;
import com.my.extend.AfterProcessor;
import com.my.handler.InitHandler;
import com.my.utils.AnnotationUtils;
import com.my.utils.PrintUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.util.ArrayList;
import java.util.List;

/**
 * @author WangLuoXin
 * &#064;Date 2024/9/12  09:43
 **/
public class Server {

    //后置处理器
    private static final List<AfterProcessor> AFTERPROCESSORS = new ArrayList<>();

    //master
    private static EventLoopGroup parentGroup;

    //worker
    private static EventLoopGroup childGroup;

    public static void start(Class<?> mainClass) {
        long start = System.currentTimeMillis();
        GlobalConfig globalConfig = Flag.parse();
        AnnotationUtils.init(mainClass, globalConfig);
        Server.parentGroup = new NioEventLoopGroup(globalConfig.getSystem().getMasterThread());
        Server.childGroup = new NioEventLoopGroup(globalConfig.getSystem().getWorkThread());
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(Server.parentGroup, Server.childGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new InitHandler(globalConfig));
            ChannelFuture future = bootstrap.bind(globalConfig.getSystem().getPort()).sync();
            PrintUtil.info("server start...");
            long end = System.currentTimeMillis();
            PrintUtil.info("Started in " + (end - start) + " ms" + ", port " + globalConfig.getSystem().getPort());
            AFTERPROCESSORS.forEach(AfterProcessor::process);
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            Server.parentGroup.shutdownGracefully();
            Server.childGroup.shutdownGracefully();
        }
    }

    /**
     * web启动前 后置扩展依赖注册
     *
     * @param afterProcessor 后置扩展器
     */
    public static void registerAfterProcessor(AfterProcessor afterProcessor) {
        AFTERPROCESSORS.add(afterProcessor);
    }

    /**
     * 停止函数
     */
    public static void serverShutdown() {
        if (null != Server.parentGroup) {
            Server.parentGroup.shutdownGracefully();
        }
        if (null != Server.childGroup) {
            Server.childGroup.shutdownGracefully();
        }
    }
}